from Tkinter import *
from Canvas import *
import sys, time

WIDTH  = 400 # width of canvas
HEIGHT = 400 # height of canvas

HPSIZE = 2 # half of point size (must be integer)
CCOLOR = "#0000FF" # blue

elementList = [] # list of elements (used by Canvas.delete(...))

polygon = []
polygon1 = []
polygon2 = []

timed = 0
dt = 0.01

def drawObjekts():
    """ draw polygon and points """
    for (p,q) in zip(polygon,polygon[1:]):
        elementList.append(can.create_line(p[0], p[1], q[0], q[1],
                                           fill=CCOLOR))
        elementList.append(can.create_oval(p[0]-HPSIZE, p[1]-HPSIZE,
                                           p[0]+HPSIZE, p[1]+HPSIZE,
                                           fill=CCOLOR, outline=CCOLOR))
            


def quit(root=None):
    """ quit programm """
    if root==None:
        sys.exit(0)
    root._root().quit()
    root._root().destroy()


def draw():
    """ draw elements """
    can.delete(*elementList)
    del elementList[:]
    drawObjekts()
    can.update()


def forward():
    global timed
    global polygon
    global polygon1
    global polygon2

    while(timed<1):
        
        timed += dt
        
    polygonmorph = []
    
    for i in range(len(polygon)):
        p1_x = timed * polygon1[i][0]
        p1_y = timed * polygon1[i][1]
        p2_x = (1-timed) * polygon2[i][0]
        p2_y = (1-timed) * polygon2[i][1]
        point1 = [p1_x,p1_y]
        point2 = [p2_x,p2_y]
        newpoint = [ point1[0] + point2[0] , point1[1] + point2[1] ]
        polygonmorph.append(newpoint)
    polygon = polygonmorph
    print polygon
    print timed
    time.sleep(0.01)
    draw()
    

def backward():
    global timed
    global polygon
    global polygon1
    global polygon2

    while(timed>0):
        timed -= dt

        polygonmorph = []
    for i in range(len(polygon)):
        p1_x = timed * polygon1[i][0]
        p1_y = timed * polygon1[i][1]
        p2_x = (1-timed) * polygon2[i][0]
        p2_y = (1-timed) * polygon2[i][1]
        point1 = [p1_x,p1_y]
        point2 = [p2_x,p2_y]
        newpoint = [ point1[0] + point2[0] , point1[1] + point2[1] ]
        polygonmorph.append(newpoint)
    polygon = polygonmorph
    print polygon
    print timed
    time.sleep(0.01)
    draw()

def readInPolygons():
    "Liest die als arg uebergebenen Polygone ein und gibt ein tupel aus zwei Listen zurueck. Diese Listen enthalten wieder zweielementige Listen mit den lokalen Koordinaten der Punkte"
    f = open(sys.argv[1],'r')
    list1 = f.readlines()
    f.close()
    f = open(sys.argv[2],'r')
    list2 = f.readlines()
    f.close()
    #make both Polygons contain same number of Points----------------------
    maxim = max (len(list1),len(list2))
    shorter = list1 if len(list1) != maxim else list2
    dazu = maxim - len(shorter)
    item = shorter[-1]  
    for i in range(dazu):
        shorter.append(item)
    #----------------------------------------------------------------------
    pointlist = []
    for line in list1:
        li = line.split()
        x = map(float,li)
        pointlist.append(x)
    pointlist2 = []
    for line in list2:
        li = line.split()
        x = map(float,li)
        pointlist2.append(x)
    return (pointlist, pointlist2)

def transformLocalIntoGlobal(pointlists):
    "Parameter pointlists ist ein Tupel wie von readInPolygons() zurueckgegeben wird. Macht aus den lokalen Koordinaten globale, so dass diese im tk-Fenster dargestellt werden koennen, ausserdem passt es die y Komponente so an das es dem KO System in tk entspricht (Ursprung links oben)"
    pl1 = pointlists[0] 
    pl2 = pointlists[1]
    helper = lambda x: x if x==HEIGHT/2 else HEIGHT - x
    pl1_glob = []
    for ele in pl1:
        pl1_glob.append(list( (ele[0]*WIDTH,helper(ele[1]*HEIGHT)) ) )
    pl2_glob = []
    for ele in pl2:
        pl2_glob.append(list( (ele[0]*WIDTH,helper(ele[1]*HEIGHT)) ) )
    return (pl1_glob, pl2_glob)

if __name__ == "__main__":
    # check parameters
    if len(sys.argv) != 3:
       print "FEHLER morph.py firstPolygon secondPolygon"
       sys.exit(-1)

    # create main window
    mw = Tk()
    mw._root().wm_title("Morphing")

    # create and position canvas and buttons
    cFr = Frame(mw, width=WIDTH, height=HEIGHT, relief="sunken", bd=1)
    cFr.pack(side="top")
    can = Canvas(cFr, width=WIDTH, height=HEIGHT)
    can.pack()
    cFr = Frame(mw)
    cFr.pack(side="left")
    bClear = Button(cFr, text="backward", command=backward)
    bClear.pack(side="left")
    bClear = Button(cFr, text="forward", command=forward)
    bClear.pack(side="left")
    eFr = Frame(mw)
    eFr.pack(side="right")
    bExit = Button(eFr, text="Quit", command=(lambda root=mw: quit(root)))
    bExit.pack()
    polygon = transformLocalIntoGlobal(readInPolygons())[0]
    polygon1 = transformLocalIntoGlobal(readInPolygons())[1]
    polygon2 = transformLocalIntoGlobal(readInPolygons())[0]
    draw()
    # start
    mw.mainloop()
    
